<script setup>
import { ref, onMounted } from 'vue'
import { mapDataInfo, layerList } from '@/utils/api.js'

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import XYZ from 'ol/source/XYZ.js';
import { FullScreen, defaults as defaultControls } from 'ol/control.js';
import MousePosition from 'ol/control/MousePosition.js';
import { createStringXY } from 'ol/coordinate.js';
import { fromLonLat, toLonLat, transform } from 'ol/proj';
import { Circle as CircleStyle, Fill, Stroke, Style, Text, Icon } from 'ol/style.js';
import { Vector as VectorSource } from 'ol/source.js';
import { Tile as TileLayer, Vector as VectorLayer, Image as ImageLayer, } from 'ol/layer.js';
import ImageWMS from 'ol/source/ImageWMS';
import GeoJSON from 'ol/format/GeoJSON.js';
import Overlay from 'ol/Overlay.js';
import l1 from '@/assets/images/l1.png'
import l2 from '@/assets/images/l2.png'

const emit = defineEmits(['sendlna'])
import dingwei from '@/assets/images/dingwei.png'

let areaId = '';
let lypath = '';
let lyname = '';
const base = ref([]);
const other = ref([]);
const lw = ref(0)
const radio = ref('天地图');
const checkList = ref([]);
const iswl = ref(false);
const wlm = ref([]);
const IsOver = ref(false)
const mol = ref([]);
const popInfo = ref({});
let container = null;
let closer = null;
let PopOverlay = null;
let olmapl = null;
let AllLayers = {};
let AllOver = {};
const xyz = new TileLayer({
    source: new XYZ({
        url: 'https://t3.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f24cec70606332017dcd39a4fb60dd11'
    }),
});

const mousePositionControl = new MousePosition({
    coordinateFormat: createStringXY(4),
    projection: 'EPSG:4326',
    className: 'wls-mouse-position',
    target: document.getElementById('mouse-position'),
});

const GSImageStyle = (feature) => {
    let src = feature.get('iconSrc');
    let anchor = [0.5, 0.5];
    //根据图标文件名 设置定位点  地图上放置的图标更改文件名即可保持一致
    if (src != '') {
        if (src.indexOf('anchor_bottom_center') != -1) {
            anchor = [0.5, 1];
        } else if (src.indexOf('anchor_bottom_left') != -1) {
            anchor = [0, 1];
        } else if (src.indexOf('anchor_bottom_right') != -1) {
            anchor = [1, 1];
        } else if (src.indexOf('anchor_center_center') != -1) {
            anchor = [0.5, 0.5];
        } else if (src.indexOf('anchor_top_center') != -1) {
            anchor = [0.5, 0];
        } else if (src.indexOf('anchor_top_left') != -1) {
            anchor = [0, 0];
        } else if (src.indexOf('anchor_top_right') != -1) {
            anchor = [1, 0];
        }
        return new Icon({
            src: feature.get('iconSrc'),
            anchor: [0.5, 1],
            scale: 0.3
        });
    }
}

const styleFunction = (feature) => {
    if (feature.getGeometry().getType() == 'Point') {
        let Point = null;
        if (feature.get('fillColor').indexOf('#') != -1) {
            Point = new Style({
                image: new CircleStyle({
                    radius: feature.get("radius"),
                    fill: new Fill({
                        color: feature.get("fillColor")
                    }),
                    stroke: new Stroke({
                        color: feature.get("borderColor"),
                        width: 2
                    })
                }),
                text: new Text({
                    font: '14px Microsoft YaHei',
                    text: feature.get('text'),
                    fill: new Fill({
                        color: feature.get('textColor')
                    }),
                    offsetY: feature.get('offsetY'),
                    // 文字描边
                    // stroke: new Stroke({
                    //     color: 'white',
                    //     width: 0
                    // }),
                })
            })
        } else {
            Point = new Style({
                image: GSImageStyle(feature),
                text: new Text({
                    font: '14px Microsoft YaHei',
                    text: feature.get('text'),
                    fill: new Fill({
                        color: feature.get('textColor')
                    }),
                    offsetY: feature.get('offsetY'),
                    // stroke: new Stroke({
                    //     color: 'white',
                    //     width: 1
                    // }),
                })
            })
        }
        return [Point]
    }

    if (feature.getGeometry().getType() == 'Polygon' || feature.getGeometry().getType() == 'MultiPolygon') {
        let Polygon = new Style({
            stroke: new Stroke({
                color: feature.get('borderColor'),
                width: 1
            }),
            fill: new Fill({
                color: feature.get("fillColor")
            }),
            text: new Text({
                font: '14px Microsoft YaHei',
                text: feature.get('text'),
                fill: new Fill({
                    color: feature.get('textColor')
                }),
                stroke: new Stroke({
                    color: 'white',
                    width: 1
                }),
            })
        })
        return [Polygon]
    }

    if (feature.getGeometry().getType() == 'LineString') {
        let LineString = new Style({
            stroke: new Stroke({
                color: feature.get('borderColor'),
                width: 3
            }),
            text: new Text({
                font: '14px Microsoft YaHei',
                text: feature.get('text'),
                fill: new Fill({
                    color: feature.get('textColor')
                }),
                stroke: new Stroke({
                    color: 'white',
                    width: 1
                }),
            })
        })
        return [LineString]
    }
}

const addGeoJson = (data, id) => {
    if (typeof (AllLayers[id]) != "undefined") {
        olmapl.removeLayer(AllLayers[id]);
        delete AllLayers[id];
    }
    let geojsonObject = {
        'type': 'FeatureCollection',
        'crs': {
            'type': 'name',
            'properties': {
                'name': 'EPSG:4326'
            }
        },
        'features': []
    };
    var MyVectorSource = new VectorSource({
        features: new GeoJSON().readFeatures(geojsonObject),
    });

    AllLayers[id] = new VectorLayer({
        source: MyVectorSource,
        style: styleFunction
    });
    var MySource = AllLayers[id].getSource();
    data.forEach((e => {
        MySource.addFeatures(
            (new GeoJSON({
                defaultDataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857'
            })).readFeatures({
                "properties": {
                    "id": e.id,
                    "borderColor": e.borderColor,
                    "fillColor": e.fillColor,
                    "radius": e.radius,
                    "offsetY": e.offsetY,
                    "iconSrc": e.iconSrc,
                    "text": e.name,
                    "data": e.data,
                    "textColor": e.textColor,
                },
                'type': 'Feature',
                'geometry': e.geojson
            }))
    }));
    AllLayers[id].set("altitudeMode", "clampToGround");
    olmapl.addLayer(AllLayers[id]);
    AllLayers[id].setZIndex(19);
}

const delLayers = (id) => {
    if (typeof (AllLayers[id]) != "undefined") {
        olmapl.removeLayer(AllLayers[id]);
        delete AllLayers[id];
    }
}

const addMoreOverlay = (data) => {
    mol.value = data;
    setTimeout(function () {
        IsOver.value = true;
        data.forEach((e, x) => {
            AllOver[e.id] = new Overlay({
                element: document.getElementById("viennas" + x),
                positioning: 'bottom-center',
                position: fromLonLat([e.lon, e.lat]),
            });
            olmapl.addOverlay(AllOver[e.id]);
        })
    }, 500)
}

const delOverlay = (id) => {
    for (let k in AllOver) {
        olmapl.removeOverlay(AllOver[k]);
        delete AllOver[k];
    }
    mol.value = [];
    IsOver.value = false;
}

const locationMap = (data) => {
    let cameraEnvirId = data.cameraEnvirId;
    lypath = data.path;
    let deviceType = data.type;
    if (deviceType == 0) {
        lyname = "实时相机"
    } else {
        lyname = "红外相机"
    }
    let params = '?cameraEnvirId=' + cameraEnvirId + '&deviceType=' + deviceType;
    mapDataInfo(params).then(res => {
        if (res.code == '200') {
            const coordinate = fromLonLat([data.lon, data.lat]);
            PopOverlay.setPosition(coordinate);
            popInfo.value = res.data;
            // olmapl.getView().setCenter(coordinate);
        }

    })
}

const initmap = () => {
    olmapl = new Map({
        target: 'mapl',
        controls: defaultControls({
            attribution: false,
            zoom: false,
            rotate: false
        }).extend([mousePositionControl]),
        layers: [xyz],
        overlays: [],
        view: new View({
            // center: fromLonLat([117.383420073467, 40.589310648968], 'EPSG:3857'), //雾灵山
            // center: fromLonLat([115.32531, 29.784082], 'EPSG:3857'),  //网湖
            // center: fromLonLat([112.11936, 35.208998], 'EPSG:3857'),  // 河南太行山猕猴国家自然保护区
            center: fromLonLat([128.66924999999998, 48.45055], 'EPSG:3857'),  // 翠北
            zoom: 11,
        }),
    });

    getlayerInfo();

    olmapl.on('singleclick', function (evt) {
        let feature = olmapl.forEachFeatureAtPixel(evt.pixel,
            function (feature) {
                return feature;
            });

        var coordinate = transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');

        addGeoJson([{
            id: 'hsfhfdh93qysdfbhtyrwe8bhf',
            name: '',
            borderColor: "",
            fillColor: '',
            offsetY: 24,
            iconSrc: dingwei,
            geojson: {
                'type': 'Point',
                'coordinates': coordinate
            }
        }], 'dgdgwgw5354bgdg')


        emit('sendlna', coordinate);

        // const coordinate = evt.coordinate;
        // PopOverlay.setPosition(coordinate);
    });
}

const SwitchLayers = (data) => {
    if (lw.value == data) {
        lw.value = 0;
    } else {
        lw.value = data;
    }
}

const addXYZ = (item, url) => {
    if (typeof (AllLayers[item]) != "undefined") {
        olmapl.removeLayer(AllLayers[item]);
        delete AllLayers[item];
    }
    AllLayers[item] = new TileLayer({
        source: new XYZ({
            url: url
        })
    },
    )
    olmapl.addLayer(AllLayers[item]);
    AllLayers[item].setZIndex(1);
};

//绘制wms类型
const drawWMS = (item, url, name, styleId, cql) => {
    if (typeof (AllLayers[item]) != "undefined") {
        olmapl.removeLayer(AllLayers[item]);
        delete AllLayers[item];
    } else {
        let params = {
            'LAYERS': name,
            'STYLES': styleId,
            'CQL_FILTER': "[" + cql + "]"
        };

        AllLayers[item] = new ImageLayer({
            source: new ImageWMS({
                url: url,
                params: params,
                serverType: 'geoserver'
            })
        })
        olmapl.addLayer(AllLayers[item]);
        AllLayers[item].setZIndex(2);
    }
};

const getlayerInfo = async () => {
    let res = await layerList(areaId)
    if (res.status == 'success') {
        base.value = res.data.base;
        other.value = res.data.polygon;
        other.value.forEach(e => {
            if (e.isShow) {
                drawWMS(e.id, e.layerUrl, e.layerName, e.styleId, e.cql);
                checkList.value.push(e.name)
            }
        })
    }
}

const openLarge = (data) => {
    if (data != null) {
        wlm.value = data;
        iswl.value = true;
    }
};

const goaut = (id) => {
    router.push({ path: lypath + '/wlsauthenticate', query: { name: lyname, groupId: id } });
}

const rtmd = (id) => {
    router.push({ path: lypath + '/wlsDetails', query: { name: lyname, id: id } });
}

onMounted(() => {
    areaId = window.sessionStorage.getItem('areaId');
})

defineExpose({ initmap, addGeoJson, addMoreOverlay, delLayers, delOverlay, locationMap })

</script>
<template>
    <div id="mapl">
        <!-- 图层 -->
        <div class="map-menu">
            <div>
                <img :src="l1" @click.stop="SwitchLayers(1)" alt="">
                <div class="mm-layers" v-if="lw == 1">
                    <el-radio-group v-model="radio">
                        <el-radio v-for="(i, index) in base" :label="i.name"
                            @change="addXYZ('baseLayer', i.layerUrl)">{{

                                i.name }}</el-radio>
                    </el-radio-group>
                </div>
            </div>
            <div>
                <img :src="l2" @click.stop="SwitchLayers(2)" alt="">
                <div class="mm-layers" v-if="lw == 2">
                    <el-checkbox-group v-model="checkList">
                        <el-checkbox v-for="(i, index) in other"
                            @change="drawWMS(i.id, i.layerUrl, i.layerName, i.styleId, i.cql)" :label="i.name" />
                    </el-checkbox-group>
                </div>
            </div>
        </div>
    </div>
</template>
<style>
#mapl {
    width: 100%;
    height: 100%;
    position: relative;
}

.My-marker {
    width: 40px;
    height: 60px;
    color: #fff;
    padding-top: 13px;
    display: flex;
    /* align-items: center; */
    justify-content: center;
    background-image: url("/src/assets/images/mark.png");
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
    overflow: hidden;
}


.map-menu {
    display: flex;
    align-items: center;
    position: absolute;
    top: 16px;
    left: 16px;
    z-index: 22;
    /* overflow: hidden; */
    cursor: pointer;
}

.map-menu>div {
    width: 40px;
    height: 40px;
    margin-left: 16px;
    position: relative;
}

.map-menu>div img {
    width: 100%;
    height: 100%;
}

.mm-layers {
    padding: 20px 0 20px 20px;
    background-color: #FFFFFF;
    border-radius: 4px;
    position: absolute;
    top: 52px;
    left: 0;
    z-index: 2;
    /* overflow: hidden; */
}

.mm-layers::before {
    content: "";
    position: absolute;
    top: -10px;
    left: 20px;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 12px solid transparent;
    border-right: 12px solid transparent;
    border-bottom: 12px solid #FFFFFF;
}

.wls-mouse-position {
    position: absolute;
    bottom: 16px;
    left: 16px;
    font-size: 0.18rem;
    color: #fff;
}


.ol-popup {
    width: 450px;
    /* height: 4.6rem; */
    padding: 0 16px;
    position: absolute;
    bottom: 12px;
    left: -50px;
    background-color: white;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    padding: 15px;
    border-radius: 10px;
    border: 1px solid #cccccc;
}

.ol-popup:after,
.ol-popup:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.ol-popup:after {
    border-top-color: white;
    border-width: 10px;
    left: 48px;
    margin-left: -10px;
}

.ol-popup:before {
    border-top-color: #cccccc;
    border-width: 11px;
    left: 48px;
    margin-left: -11px;
}

.popup-title {
    width: 100%;
    height: .56rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.popup-title>div {
    height: 100%;
    display: flex;
    align-items: center;
}

.popup-title>div span {
    margin-left: 8px;
    font-size: .16rem;
}

.popup-img {
    width: 100%;
    height: 3rem;
    background-color: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}


.popup-img img {
    width: 100%;
    height: 100%;
}

.popup-img video {
    width: 100%;
    height: 100%;
}

.popup-list-item {
    width: 100%;
    padding: 0.16rem 0;
    display: flex;
    align-items: center;
    color: #606266;
    border-bottom: 1px solid #DCDFE6;
    overflow: hidden;
}

.popup-list-span {
    display: inline-block;
    margin-left: 0.08rem;
    line-height: 2;
    white-space: nowrap;
    /* 禁止换行 */
    overflow: hidden;
    /* 超出部分隐藏 */
    text-overflow: ellipsis;
    /* 超出部分显示省略号 */
}

.popup-list-s {
    width: 1px;
    height: 0.18rem;
    margin: 0 .24rem;
    background-color: #DCDFE6;
}

.popupc {
    font-size: 0.16rem;
    color: var(--wls-color);
    text-decoration: underline;
    cursor: pointer;
}
</style>